<html>
<head>
<link rel="stylesheet" type="text/css" href="http://www.mattfilion.com/styles/styles.css" />
<script type="text/javascript" src="http://www.mattfilion.com/script/jquery-1.2.6.pack.js"></script> 
<script type="text/javaScript" src="http://www.mattfilion.com/chili/jquery.chili-2.0.js"></script> 
<script type="text/javascript"> 
    ChiliBook.recipeFolder = "http://www.mattfilion.com/chili/";  
</script>  
</head>
<body>
<div id="content">
<h1>Read Me</h1>
<p>I created this plug-in for my own personal usage and am releasing it for anyone to do 
anything with they see fit. If you'd like see some new features you can either 
request them (matt@mattfilion.com) or submit me a patch. The source is included 
in the jar, i dont have a sourceforge project for this yet because there simply
hasnt been any interest in this beyond my own.</p>
<ol>
	<li><a href="#whyDidYouDoThis">Why did you do this?</a></li>
	<li><a href="#simpleHowTo">Simple How To</a></li>
	<li><a href="#advanced">Advanced</a></li>
	<li><a href="gotcha">Gotchas, Ideas and what I do.</a></li>
	
</ol>
<h2><a name="whyDidYouDoThis">1 Why did you do this?</a></h2>
<p>I was doing quite a bit of web 2.0 development that included the generation 
of XML to and from domain objects within my application. This was an incredibly
tedious task to write custom generation and parsing off so then I decided to 
make use of JAXB. From the first few examples I created using JAXB I noticed 
a lot of boilerplate code that would be created so then i decided to to use
an intercepter and result type (within struts 2) to remove the need for all of
this. So thats when the first version was born and from there its just naturally
matured to the state it is in now.</p>
<p>I did look into using the JSON plug-in but JSON has a few security concerns that
I just didn't want to deal with (this plug-in was created in a data sensitive
environment).</p>
<h2><a name="simpleHowTo">2 Simple How To</a></h2>
<p>So there is a lot of JavaDoc on the intercepter and result type declared in
the jar file, but i'd annoy a lot of people if i directed you to that. So i'll
give you a more detailed step by step how-to for the most basic scenario in how
to use this plug-in.</p>
<p>This example is going to assume your using Java 1.6 and know how to use
annotations, since its the simplest scenario.</p>
<ol>
	<li><h3>A Simple JAXB Entity</h3>
		<p>So create a simple java bean and give it the proper JAXB annotations.</p>
		<pre><code class="java">
package example;

import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author You!
 */
//JAXB
@XmlRootElement
public class SimpleBean {
    
    private String value;

    public SimpleBean(){
    }

    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}
		</code></pre>
		<p>As you can see this is just a simple bean, that also contains the JAXB 
		@XmlRootElement annotation.</p>
	</li>
	<li><h3>jaxb.index</h3>
		<p>So now that you have a JAXB annotated bean you need to tell JAXB that 
		it is okay to be marshalled and unmarshalled. You do this by adding a 
		regular text file named jaxb.index in the package with the bean you
		just created. Here is what your jaxb.index should contain.</p>
		<pre><code>
SimpleBean

		</code></pre>
		<p>The format of this file is really simple as you can see.</p>
		<p class="note">So its worth noting that you could also use an ObjectFactory
		to initialize your JAXB entities. However I'm not going to go into it for 2
		reasons. I only ever use the jaxb.index, and its the simpler scenario.
		If you already use an ObjectFactory or want to use one, do a quick google or
		just make the necessary adjustments.</p>
	</li>
	<li><h3>Action</h3>
	<p>Now that you have an entity you need something to process your request and 
	initialize your entity. So the below example action does just that.</p>
	<pre><code class="java">
package example;
/**
 * @author You!
 */
public class SimpleAction {
    
    private SimpleBean simpleBean;

    public SimpleAction(){}
    
    public execute(){
    	this.simpleBean = new SimpleBean();
    	this.simpleBean.setValue("Hello World");
    
    	return "simpleBeanResult";
    }

    public String getSimpleBean() {
        return simpleBean;
    }

    public void setSimpleBean(String simpleBean) {
        this.simpleBean = simpleBean;
    }
}
	</code></pre>
	<p>So when this action is executed it will create the member level variable, 
	simpleBean and set its value to "Hello World". Nothing worth noting here.<p>
	</li>
	<li><h3>Add The Plug-in</h3>
	<p>So now you need to add the plug-in to your class path. This is typicially done
	by placing it into the WEB-INF\lib directory of your Web Project.</p>
	</li>
	<li><h3>Struts.xml Configuration</h3>
	<p>Now we need to do a handful of things to tell struts to use the action and
	utilize the plug-in's capabilities. I'll give you the example first and go over
	it below.</p>
	<pre><code class="xml">
&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"&gt;
	&lt;struts&gt;
	&lt;package name="root" extends="jaxb-communicate"&gt;
		&lt;interceptors&gt;        
			&lt;interceptor-stack name="DEFAULT_STACK"&gt;
				&lt;interceptor-ref name="basicStack"/&gt;
				&lt;interceptor-ref name="staticParams"/&gt;
				&lt;interceptor-ref name="xmlUnMarshaller"/&gt;
			&lt;/interceptor-stack&gt;
		&lt;/interceptors&gt;
		&lt;action name="simpleAction" class=example."SimpleAction"&gt;
			&lt;interceptor-ref name="DEFAULT_STACK"/&gt;
			&lt;result name="simpleBeanResult" type="xmlMarshalling"&gt;
				&lt;param name="packageContext"&gt;example.simple&lt;/param&gt;
				&lt;param name="objectToMarshall"&gt;simpleBean&lt;/param&gt;
			&lt;/result&gt;
		&lt;/action&gt;
	&lt;/package&gt;
&lt;/struts&gt;
	</code></pre>
	<p>So there are 3 main things of note within this struts.xml file. The first
	is on the package element where we extend "jaxb-communicate" (probably not the
	greatest name in the world). This tells struts to extend the declarations defined
	in the struts2-jaxb-plugin.jar that you've added to your classpath.</p>
	<p>The next thing you should notice is the declaration of "xmlUnMarshaller". You
	don't see a declaration of this object because its already defined in the struts.xml
	of the struts2-jaxb-plugin.jar.</p>
	<p>The last thing you see is within the action definition. There is a result with the
	type of "xmlMarshalling". This again points to a result type defined in the struts.xml
	file of the struts2-jaxb-plugin.jar. This result type has 2 attributes, packageContext
	and objectToMarshall. So thes are pretty simple. The packageContext points to the
	package with the jaxb.index file and your java bean (SimpleBean). The objectToMarshall
	attribute points to the bean defined on the Action that you want marshalled into XML.</p> 
	</li>
	<li><h3>Execute your test.</h3>
	<p>So now if you start up struts and go to your application and go to simpleAction.action
	you will see the output.</p>
	<pre><code class="xml">
&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;simpleBean&gt;
    &lt;value&gt;ello World&lt;/value&gt;
&lt;/simpleBean&gt;
	</code></pre>
	<p class="note">I'm assuming you will view this in a browser, which should format it for you.
	Otherwise this will all be in a single unformatted line. See advanced for outputting formatted
	XML.</p>
	<p>So the output is exactly what you'd expect. Now, lets make an update to our action so
	you can see how it instantiates objects from XML. I've done a quick update to the SimpleAction
	to output the value of simpleBean if it is not null. This will also have the output of the
	SimpleAction be the same as the XML input.</p>
	<pre><code class="java">
package example;
/**
 * @author You!
 */
public class SimpleAction {
    
    private SimpleBean simpleBean;

    public SimpleAction(){}
    
    public execute(){
    	if(simpleBean==null){
    		this.simpleBean = new SimpleBean();
    		this.simpleBean.setValue("Hello World");
    	} else {
    		System.out.println("simpleBean:"+simpleBean);
    		System.out.println("simpleBean:"+simpleBean.getValue());
    	}
    
    	return "simpleBeanResult";
    }

    public String getSimpleBean() {
        return simpleBean;
    }

    public void setSimpleBean(String simpleBean) {
        this.simpleBean = simpleBean;
    }
}
	</code></pre>
	<p>Now to test this you have to use a complex URL, this sucks for this type
	of test but in all real cases you will have XML generated from JavaScript
	so this wouldn't be so painful. I'll help you out by providing you with
	an example URL.</p>
	<textarea style="width: 500px;height:60px;">simpleAction.action?jaxbPackageContext=example&jaxbXML=<simpleBean><value>This bean has a new value!</value></simpleBean></textarea>
	<p>So this URL has 2 arguments. jaxbPackagContext, which is the same as the
	package context declared on the result. Its the package containing the 
	jaxb.index file. The second argument is the jaxbXML which is of course the
	XML you want to send to the action and have marshaled into an object. When
	you execute this action you should see the exact same XML displayed in the
	web browser and something similar to this on the console.</p>
	<pre><code type="text">
simpleBean:example.SimpleBean@198a455
simpleBean:This bean has a new value!
	</code></pre>
	</li>
</ol>
<h2><a name="advanced">3 Advanced</a></h2>
<p>So beyond the "Simple How To" that has already been written (above), there are
some additional settings you can declare on both the intercepter and result type
to further customize it to your needs. Here is a breakdown of the attributes
defined on the intercepter.</p>
<ul>
	<li>packageContextParameterName - This allows you to change the parameter that
	the intercepter will look for the PackageContext value within. So if you assign
	"myPackageContext" then your url's for submitting XML would need to resemble
	"myAction.action?myPackageContext=myPackage&jaxbXML=<...../>"<li>
	<li>xmlParameterName - Similar to the previous attribute this allows you to change
	the request parameter that the XML will be retrieved from.</li>
	<li>packageContext - This attribute allows you to "hard code" the package
	context value into the intercepter. This is handy when you only have a single
	package for all entities. You would now only need to include the XML in the
	post to the action.</li>
	<li>putPackageContextInStack - This attribute will place the package context
	into the stack under the key of "_packageContext". This is handy if you need
	it anywhere within your Actions execution flow, or if you want to further simplify
	things and have your result type use the package context provided by the
	intercepter.</li>
	<li>straightXML - This is a bit more complicated. I havn't used it yet but the
	idea is that you will post ONLY XML directly to the action and the intercepter
	would look for all of the XML as the first key in the parameter stack. Also if
	the package request is not provided it will look within the XML for the package
	context. Its assumed that the package context will be set on the root element
	under the attribute "packageContext". So a url looking like this 
	myAction.action?<entity class=><value>Hi</value></entity>
	would look for the "entity" object on the action and set its "value" to "hi".</li>
</ul>
<p>In addition you can use the following attributes on the result type definitions.</p>
<ul>
	<li>packageContext - The package context that defines the jaxb.index file for
	the "objectToMarshall".</li>
	<li>objectToMarshall - The object defined within the stack or on the action that
	will be marshalled into XML.</li>
	<li>gzipResult - If set to true it will gzip the stream of xml sent to the
	browser. It will check the "Accept-Encoding" header value first to make sure
	that gzip is accepted by the browser.</li>
	<li>isOutputFormatted - If set to true the XML output by this result will
	be friendly formatted with tabs and line breaks.</li>
</ul>
<h2><a name="gotcha">4 Gotchas, Ideas and what I do.</a></h2>
<p>So there are a few things that i figured out while using this plug-in that
I don't want you to have to struggle through. I tried to code around as much of
it as possible to make things as easy for you as possible but some things i just
didn't have time to figure out or couldn't.</p>
<ul>
	<li><h3>JAXBList</h3>
	<p>So you cannot directly marshal a List of entities into XML (at least I couldn't
	figure out how to do it). So instead you have to wrap your collection into a 
	custom list thats defined within a jaxb.index file. I use the below "JAXBList" 
	object when i need to output lists.</p>
	<pre><code class="java">
/**
 * @author Matt Filion
 *
 */
@XmlRootElement(name="list")
public class JAXBList&lt;T&gt; {
    
    private List&lt;T&gt; items = null;
    
    /**
     * 
     */
    public JAXBList() {
        items = new ArrayList&lt;T&gt;();
    }

    /**
     * 
     * @param item
     */
    public void add(T item){
        items.add(item);
    }
    
    /**
     * @return the items
     */
    @XmlAnyElement
    public List&lt;T&gt; getItems() {
        return items;
    }

    /**
     * @param items the items to set
     */
    public void setItems(List&lt;T&gt; items) {
        this.items = items;
    }
}
	</code></pre></li>
	<li><h3>Return within action same as object name.</h3>
	<p>So your looking at the title of this going...what? So to explain what I mean.
	The idea behind this is 2 fold. First define all of your result types globally
	and also give them the same name as the entity they are marshaling. This makes
	your code more friendly. WHen an action returns a value of "simpleBean" and there
	is a private SimpleBean simpleBean member variable you have a good idea of what's
	going to get marshaled.</li>
	<li><h3>Errors</h3>
	<p>When there is an exception while trying to marshal your entity into XML it will
	format the exception into XML as well. Its structure will look like the following.</p>
	<pre><code class="xml">
&lt;exception&gt;
	&lt;type&gt;{The name of the exception}&lt;/type&gt;
	&lt;message&gt;{The message of the exception}&lt;/message&gt;
	&lt;gzipResult&gt;{The gzipResult value when the exception occurred}&lt;/gzipResult&gt;
	&lt;isOutputFormatted&gt;{The isOutputFormatted value when the exception occurred}&lt;/isOutputFormatted&gt;
	&lt;objectToMarshall&gt;{The objectToMarshall value when the exception occurred}&lt;/objectToMarshall&gt;
	&lt;packageConext&gt;{The value of the packageContext when the exception occurred}&lt;/packageConext&gt;
&lt;/exception&gt;
	</code></pre>
	</li>
	<li><h3>JAXB1</h3>
	<p>I am pretty sure it wont work, but give it a try if you like! Let me know 
	what happens. :)</p>
	</li>
	<li><h3>Use a TextArea for XML</h3>
	<p>One lesson i learned is that when sending XML to the server, especially if its large,
	always use a text area. This ensures that the value of the text will not be changed.
	Inputs remove line breaks.</p>
	</li>
	<li><h3>What's my setup</h3>
	<p>For anyone who cares i've included what my struts XML file looks like and how I
	like to use this plug-in.</p>
	<pre><code class="xml">
&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"&gt;
&lt;struts&gt;
	&lt;package name="root" extends="jaxb-communicate"&gt;
		&lt;interceptors&gt;
			&lt;interceptor-stack name="DEFAULT_STACK"&gt;
				&lt;interceptor-ref name="basicStack" /&gt;
				&lt;interceptor-ref name="staticParams" /&gt;
				&lt;interceptor-ref name="xmlUnMarshaller"&gt;
					&lt;!-- This is a small project with one package containing
						my entities. --&gt;
					&lt;param name="packageContext"&gt;com.my.entities&lt;/param&gt;
					&lt;!-- The result will use the package context defined
						above. --&gt;
					&lt;param name="putPackageContextInStack"&gt;true&lt;/param&gt;
				&lt;/interceptor-ref&gt;
			&lt;/interceptor-stack&gt;
		&lt;/interceptors&gt;

		&lt;default-interceptor-ref name="DEFAULT_STACK" /&gt;

		&lt;global-results&gt;
			&lt;!-- This mapping is for a Page object. --&gt;
			&lt;result name="page" type="xmlMarshalling"&gt;
				&lt;param name="objectToMarshall"&gt;page&lt;/param&gt;
				&lt;param name="gzipResult"&gt;true&lt;/param&gt;
			&lt;/result&gt;
			&lt;!-- etc... --&gt;
		&lt;/global-results&gt;

		&lt;!-- Because I'm only communicating VIA XML on this action it
			does not need any response declarations. It will use
			the globally defined results.  --&gt;
		&lt;action name="myAction*" class="com.my.Action" method="{1}" /&gt;
	&lt;/package&gt;
&lt;/struts&gt;
	</code></pre>
	</li>
	<li>JAXB2 Libraries - TODO</li>
</ul>
</div>
</body>
</html>